package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.contans.materia.MateriaContans;
import com.heima.common.contans.message.NewsAutoScanConstants;
import com.heima.common.contans.message.WmNewsMessageConstants;
import com.heima.common.exception.CustomException;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dtos.NewsAuthDto;
import com.heima.model.wemedia.dtos.WmNewsDto;
import com.heima.model.wemedia.dtos.WmNewsPageReqDto;
import com.heima.model.wemedia.pojos.WmMaterial;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmNewsMaterial;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.model.wemedia.vo.WmNewsVo;
import com.heima.utils.threadlocal.WmThreadLocalUtils;
import com.heima.wemedia.mapper.WemediaMapper;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Log4j2
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper , WmNews> implements WmNewsService {
    @Value("${fdfs.url}")
    private String fdfsUri;

    @Override
    public ResponseResult findList(WmNewsPageReqDto dto) {
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        LambdaUpdateWrapper<WmNews> wrapper = new LambdaUpdateWrapper<>();
        if(dto.getStatus() != null){
            wrapper.eq(WmNews::getStatus , dto.getStatus());
        }
        if(dto.getChannelId() != null){
            wrapper.eq(WmNews::getChannelId , dto.getChannelId());
        }
        if(dto.getKeyword() != null){
            wrapper.like(WmNews::getTitle , dto.getKeyword());
        }
        if(dto.getBeginPubdate() != null && dto.getEndPubdate() != null){
            wrapper.between(WmNews::getCreatedTime , dto.getBeginPubdate() , dto.getEndPubdate());
        }
        //获取当前登录的用户
        WmUser user = WmThreadLocalUtils.getUser();
        if(user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        wrapper.eq(WmNews::getUserId , user.getId());
        wrapper.orderByDesc(WmNews::getPublishTime);
        IPage page = new Page(dto.getPage() , dto.getSize());
        IPage page1 = page(page, wrapper);
        PageResponseResult result = new PageResponseResult(dto.getPage() , dto.getSize() , (int)page1.getTotal());
        result.setData(page1.getRecords());
        result.setHost(fdfsUri);
        return result;
    }

    @Override
    public ResponseResult summitNews(WmNewsDto dto, short submit) {
        if (dto == null || dto.getContent() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto , wmNews);
        if(MateriaContans.WM_NEWS_TYPE_AUTO.equals(dto.getType())){
            wmNews.setType(null);
        }
        if(dto.getImages() != null && dto.getImages().size() > 0){
            wmNews.setImages(dto.getImages().toString().replace("[","").
                    replace("]","").replace(fdfsUri ,"").replace(" ",""));
        }
        saveWmNews(wmNews , submit);

        //关联文章与素材的关系
        String content = dto.getContent();
        List<Map> list = JSON.parseArray(content, Map.class);
        List<String> materials  = ectractUrlInfo(list);

        //关联内容中的图片与素材的关系
        if(submit == WmNews.Status.SUBMIT.getCode() && materials.size() != 0){
            ResponseResult result = saveRelativeInfoForContent(materials , wmNews.getId());
            if(result != null){
                return result;
            }
        }

        if (submit == WmNews.Status.SUBMIT.getCode()){
            ResponseResult result = saveRelativeInfoForCover(dto , materials , wmNews);
            if(result != null){
                return result;
            }
        }


        return null;
    }

    private ResponseResult saveRelativeInfoForCover(WmNewsDto dto, List<String> materials, WmNews wmNews) {
        List<String> images = dto.getImages();
        if (dto.getType().equals(MateriaContans.WM_NEWS_TYPE_AUTO)){
            if(materials.size() > 0 && materials.size() <= 2){
                wmNews.setType(MateriaContans.WM_NEWS_SINGLE_IMAGE);
                images = materials.stream().limit(1).collect(Collectors.toList());
            }else if (materials.size() > 2){
                wmNews.setType(MateriaContans.WM_NEWS_MANY_IMAGE);
                images = materials.stream().limit(3).collect(Collectors.toList());
            }else{
                wmNews.setType(MateriaContans.WM_NEWS_NONE_IMAGE);
            }
            if(images != null && images.size() > 0){
                wmNews.setImages(images.toString().replace("[","").
                        replace("]","").replace(fdfsUri ,"").replace(" ",""));
            }
            updateById(wmNews);
        }
        //保存封面图片与素材的关系
        if(images != null && images.size() > 0){
            ResponseResult result = saveRelativeInfoForImage(images , wmNews.getId());
            if (result != null){
                return result;
            }
        }

        return null;
    }

    private ResponseResult saveRelativeInfoForImage(List<String> images, Integer id) {
        List<String> materials = new ArrayList<>();
        for (String image : images) {
            materials.add(image.replace(fdfsUri , ""));
        }
        return saveRelativeInfo(materials , id , MateriaContans.WM_COVER_REFERENCE);
    }

    /**
     *
     * @param materials
     * @param newsId
     * @return
     */
    private ResponseResult saveRelativeInfoForContent(List<String> materials, Integer newsId) {
        return saveRelativeInfo(materials , newsId , MateriaContans.WM_CONTENT_REFERENCE);
    }

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    private ResponseResult saveRelativeInfo(List<String> materials, Integer newsId, Short type) {
        LambdaQueryWrapper<WmMaterial> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(WmMaterial::getUrl , materials);
        wrapper.eq(WmMaterial::getUserId , WmThreadLocalUtils.getUser().getId());
        List<WmMaterial> dbMaterials = wmMaterialMapper.selectList(wrapper);
        if(dbMaterials == null || dbMaterials.size() == 0){
            throw new CustomException(ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "没有查询到素材信息"));
        }
        List<String> materialIds = new ArrayList<>();
        Map<String, Integer> uriIdMap = dbMaterials.stream().collect(Collectors.toMap(WmMaterial::getUrl, WmMaterial::getId));
        for (String val : materials) {
            String materialId = String.valueOf(uriIdMap.get(val));
            if("null".equals(materialId)){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "应用图片失效");
            }
            materialIds.add(materialId);
            }
        wmNewsMaterialMapper.ssaveRelations(materialIds , newsId , type);
        return null;
    }

    private List<String> ectractUrlInfo(List<Map> list) {
        List<String> materials = new ArrayList<>();
        for (Map map : list) {
            if (map.get("type").equals(MateriaContans.WM_NEWS_TYPE_IMAGE)){
                String imageUrl = (String) map.get("value");
                imageUrl = imageUrl.toString().replace(fdfsUri, "");
                materials.add(imageUrl);
            }
        }
        return materials;
    }

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private KafkaTemplate kafkaTemplate;
    /**
     * 保存或修改文章
     * @param wmNews
     * @param submit
     */
    private void saveWmNews(WmNews wmNews , short submit) {
        wmNews.setStatus(submit);
        wmNews.setCreatedTime(new Date());
        wmNews.setEnable((short)1);
        wmNews.setUserId(WmThreadLocalUtils.getUser().getId());
        boolean flag = false;
        if(wmNews.getId() == null){
            flag = save(wmNews);
        }else {
            LambdaUpdateWrapper<WmNewsMaterial> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(WmNewsMaterial::getNewsId , wmNews.getId());
            wmNewsMaterialMapper.delete(wrapper);
            flag = updateById(wmNews);
        }
        if(flag){
            kafkaTemplate.send(NewsAutoScanConstants.WM_NEWS_AUTO_SCAN_TOPIC,JSON.toJSONString(wmNews.getId()));
        }

    }

    /**
     * 根据id修改文章
     * @param id
     * @return
     */
    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if(id == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "文章id不存在");
        }
        WmNews wmNews = getById(id);
        if (wmNews == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ResponseResult result = ResponseResult.okResult(wmNews);
        result.setHost(fdfsUri);
        return result;
    }

    @Override
    public ResponseResult delNews(Integer id) {
        if(id == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "文章id不存在");
        }
        WmNews wmNews = getById(id);
        if (wmNews == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if(wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode()) && wmNews.getEnable().equals(MateriaContans.WM_NEWS_ENBLE_UP)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "文章已发布，上架，不能删除");
        }
        LambdaQueryWrapper<WmNewsMaterial> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WmNewsMaterial::getNewsId , wmNews.getId());
        wmNewsMaterialMapper.delete(wrapper);
        removeById(wmNews.getId());

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //发布文章的上下架
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        //检查参数
        if (dto == null || dto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = getById(dto.getId());
        if (wmNews == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "文章不存在");
        }
        //判断文章有没有发布
        if(!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID , "文章还没有发布，不能上下架");
        }
        //修改文章状态
        if (dto.getEnable() != null && dto.getEnable() > -1 && dto.getEnable() <2){
            if (wmNews.getArticleId() != null){
                Map<String , Object> map = new HashMap<>();
                map.put("articleId" , wmNews.getArticleId());
                map.put("enable" , wmNews.getEnable());
                kafkaTemplate.send(WmNewsMessageConstants.WM_NEWS_UP_OR_DOWN_TOPIC, JSON.toJSONString(map));
            }
            LambdaUpdateWrapper<WmNews> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(WmNews::getId , dto.getId())
                    .set(WmNews::getEnable , dto.getEnable());
            update(wrapper);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public List<Integer> findRelease() {
        LambdaQueryWrapper<WmNews> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WmNews::getStatus , 8)
                .le(WmNews::getPublishTime , new Date());
        List<WmNews> list = list(wrapper);
        List<Integer> integers = list.stream().map(WmNews::getId).collect(Collectors.toList());
        return integers;
    }

    @Autowired
    private WmNewsMapper wmNewsMapper;
    //查询文章列表
    @Override
    public PageResponseResult findList(NewsAuthDto dto) {
        //检查惨数
        dto.checkParam();
        //设置分页
        dto.setPage((dto.getPage()-1)*dto.getSize());
        if (dto.getTitle() != null){
            dto.setTitle("%"+dto.getTitle()+"%");
        }
        //保存数据
        List<WmNewsVo> wmNewsVo = wmNewsMapper.findListAndPage(dto);
        int count = wmNewsMapper.findListCount(dto);
        PageResponseResult responseResult = new PageResponseResult(dto.getPage() , dto.getSize() , count);
        responseResult.setData(wmNewsVo);
        //返回
        return responseResult;
    }

    @Autowired
    private WemediaMapper wemediaMapper;
    //根据id查询文章详情
    @Override
    public WmNewsVo findWmNewsVo(Integer id) {
        WmNews wmNews = getById(id);
        WmUser wmUser = null;
        if (wmNews != null){
            wmUser = wemediaMapper.selectById(wmNews.getUserId());
        }
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews , wmNewsVo);
        if (wmUser != null){
            wmNewsVo.setAuthorName(wmUser.getName());
        }
        return wmNewsVo;
    }
}
